//! API请求处理器

use std::sync::Arc;
use serde::Deserialize;

use nacos_core::traits::{NamingService, ConfigService};
use nacos_core::{ServiceInstance, Result, NacosError};
use crate::cluster_adapter::ClusterIntegrationManager;

use super::{ApiResponse, Response, Request};

/// 命名服务处理器
pub struct NamingHandler {
    naming_service: Arc<dyn NamingService>,
}

impl NamingHandler {
    pub fn new(naming_service: Arc<dyn NamingService>) -> Self {
        Self { naming_service }
    }

    /// 处理注册实例请求
    pub async fn handle_register_instance(&self, request: super::Request) -> Result<super::Response> {
        #[derive(Deserialize)]
        struct RegisterRequest {
            namespace: String,
            service_name: String,
            ip: String,
            port: u16,
            weight: f64,
            healthy: bool,
            enabled: bool,
            ephemeral: bool,
            cluster_name: Option<String>,
            metadata: Option<std::collections::HashMap<String, String>>,
        }

        let req: RegisterRequest = serde_json::from_slice(&request.body)
            .map_err(|e| NacosError::Validation(format!("Invalid request body: {}", e)))?;

        let instance = ServiceInstance::new(
            req.service_name.clone(),
            "DEFAULT".to_string(),
            req.ip.clone(),
            req.port,
        );

        self.naming_service
            .register_instance(&instance)
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(());
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理注销实例请求
    pub async fn handle_deregister_instance(&self, request: super::Request) -> Result<super::Response> {
        #[derive(Deserialize)]
        struct DeregisterRequest {
            namespace: String,
            service_name: String,
            ip: String,
            port: u16,
        }

        let req: DeregisterRequest = serde_json::from_slice(&request.body)
            .map_err(|e| NacosError::Validation(format!("Invalid request body: {}", e)))?;

        let instance_id = format!("{}#{}#{}#{}:{}", 
            req.namespace, 
            "DEFAULT", 
            req.service_name, 
            req.ip, 
            req.port
        );

        self.naming_service
            .deregister_instance(&req.namespace, "DEFAULT", &req.service_name, &instance_id)
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(());
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理获取实例列表请求
    pub async fn handle_get_instances(&self, request: super::Request) -> Result<super::Response> {
        let namespace = request.query_params.get("namespace")
            .ok_or_else(|| NacosError::Validation("Missing namespace parameter".to_string()))?;
        let service_name = request.query_params.get("service_name")
            .ok_or_else(|| NacosError::Validation("Missing service_name parameter".to_string()))?;
        let healthy_only = request.query_params.get("healthy_only")
            .and_then(|v| v.parse().ok())
            .unwrap_or(true);

        let instances = if healthy_only {
            self.naming_service
                .get_healthy_instances(namespace, "DEFAULT", service_name)
                .await
                .map_err(|e| NacosError::Internal(e.to_string()))?
        } else {
            self.naming_service
                .get_all_instances(namespace, "DEFAULT", service_name)
                .await
                .map_err(|e| NacosError::Internal(e.to_string()))?
        };

        let response = ApiResponse::success(instances);
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理获取服务列表请求
    pub async fn handle_list_services(&self, request: super::Request) -> Result<super::Response> {
        let namespace = request.query_params.get("namespace")
            .ok_or_else(|| NacosError::Validation("Missing namespace parameter".to_string()))?;
        let page = request.query_params.get("page")
            .and_then(|v| v.parse().ok())
            .unwrap_or(1);
        let page_size = request.query_params.get("page_size")
            .and_then(|v| v.parse().ok())
            .unwrap_or(100);

        let services = self.naming_service
            .get_all_service_names(namespace, Some("DEFAULT"))
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(services);
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }
}

/// 配置服务处理器
pub struct ConfigHandler {
    config_service: Arc<dyn ConfigService>,
}

impl ConfigHandler {
    pub fn new(config_service: Arc<dyn ConfigService>) -> Self {
        Self { config_service }
    }

    /// 处理发布配置请求
    pub async fn handle_publish_config(&self, request: super::Request) -> Result<super::Response> {
        #[derive(Deserialize)]
        struct PublishRequest {
            namespace: String,
            group: String,
            data_id: String,
            content: String,
        }

        let req: PublishRequest = serde_json::from_slice(&request.body)
            .map_err(|e| NacosError::Validation(format!("Invalid request body: {}", e)))?;

        let success = self.config_service
            .publish_config(&req.namespace, &req.group, &req.data_id, &req.content)
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(success);
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理获取配置请求
    pub async fn handle_get_config(&self, request: super::Request) -> Result<super::Response> {
        let namespace = request.query_params.get("namespace")
            .ok_or_else(|| NacosError::Validation("Missing namespace parameter".to_string()))?;
        let group = request.query_params.get("group")
            .ok_or_else(|| NacosError::Validation("Missing group parameter".to_string()))?;
        let data_id = request.query_params.get("data_id")
            .ok_or_else(|| NacosError::Validation("Missing data_id parameter".to_string()))?;

        let config = self.config_service
            .get_config(namespace, group, data_id)
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(config);
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理删除配置请求
    pub async fn handle_delete_config(&self, request: super::Request) -> Result<super::Response> {
        #[derive(Deserialize)]
        struct DeleteRequest {
            namespace: String,
            group: String,
            data_id: String,
        }

        let req: DeleteRequest = serde_json::from_slice(&request.body)
            .map_err(|e| NacosError::Validation(format!("Invalid request body: {}", e)))?;

        let success = self.config_service
            .remove_config(&req.namespace, &req.group, &req.data_id)
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(success);
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理添加监听器请求
    pub async fn handle_add_listener(&self, request: super::Request) -> Result<super::Response> {
        #[derive(Deserialize)]
        struct ListenerRequest {
            namespace: String,
            group: String,
            data_id: String,
            listener_id: String,
        }

        let req: ListenerRequest = serde_json::from_slice(&request.body)
            .map_err(|e| NacosError::Validation(format!("Invalid request body: {}", e)))?;

        // 注：实际实现需要创建EventListener，这里简化处理
        // 在API handler中，监听通常通过长轮询或WebSocket实现

        let response = ApiResponse::success(());
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }
}

/// 集群处理器
pub struct ClusterHandler {
    cluster_integration: Arc<ClusterIntegrationManager>,
}

impl ClusterHandler {
    pub fn new(cluster_integration: Arc<ClusterIntegrationManager>) -> Self {
        Self { cluster_integration }
    }

    /// 处理获取集群状态请求
    pub async fn handle_get_cluster_status(&self, _request: super::Request) -> Result<super::Response> {
        let status = self.cluster_integration
            .get_cluster_status()
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(status);
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理获取集群节点列表请求
    pub async fn handle_get_cluster_nodes(&self, _request: super::Request) -> Result<super::Response> {
        let nodes = self.cluster_integration
            .get_cluster_nodes()
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(nodes);
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理添加集群节点请求
    pub async fn handle_add_cluster_node(&self, request: super::Request) -> Result<super::Response> {
        let node: nacos_core::ClusterNode = serde_json::from_slice(&request.body)
            .map_err(|e| NacosError::Validation(format!("Invalid request body: {}", e)))?;

        self.cluster_integration
            .add_cluster_node(node)
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(());
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }

    /// 处理移除集群节点请求
    pub async fn handle_remove_cluster_node(&self, request: super::Request) -> Result<super::Response> {
        #[derive(Deserialize)]
        struct RemoveNodeRequest {
            node_id: String,
        }

        let req: RemoveNodeRequest = serde_json::from_slice(&request.body)
            .map_err(|e| NacosError::Validation(format!("Invalid request body: {}", e)))?;

        self.cluster_integration
            .remove_cluster_node(&req.node_id)
            .await
            .map_err(|e| NacosError::Internal(e.to_string()))?;

        let response = ApiResponse::success(());
        let body = serde_json::to_vec(&response).unwrap();

        Ok(super::Response {
            status_code: 200,
            headers: [("Content-Type".to_string(), "application/json".to_string())]
                .iter()
                .cloned()
                .collect(),
            body,
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use nacos_core::MockNamingService;
    use nacos_core::MockConfigService;

    #[tokio::test]
    async fn test_naming_handler() {
        let naming_service = Arc::new(MockNamingService::new());
        let handler = NamingHandler::new(naming_service);

        let request = super::Request {
            method: "POST".to_string(),
            path: "/naming/register".to_string(),
            headers: std::collections::HashMap::new(),
            query_params: std::collections::HashMap::new(),
            body: br#"{
                "namespace": "test-ns",
                "service_name": "test-service",
                "ip": "127.0.0.1",
                "port": 8080,
                "weight": 1.0,
                "healthy": true,
                "enabled": true,
                "ephemeral": true
            }"#.to_vec(),
            remote_addr: "127.0.0.1".to_string(),
        };

        let response = handler.handle_register_instance(request).await;
        assert!(response.is_ok());
    }

    #[tokio::test]
    async fn test_config_handler() {
        let config_service = Arc::new(MockConfigService::new());
        let handler = ConfigHandler::new(config_service);

        let request = super::Request {
            method: "POST".to_string(),
            path: "/config/publish".to_string(),
            headers: std::collections::HashMap::new(),
            query_params: std::collections::HashMap::new(),
            body: br#"{
                "namespace": "test-ns",
                "group": "test-group",
                "data_id": "test-data",
                "content": "test-content"
            }"#.to_vec(),
            remote_addr: "127.0.0.1".to_string(),
        };

        let response = handler.handle_publish_config(request).await;
        assert!(response.is_ok());
    }
}